
<template>
    <div class="threeJsPrc14">
      <!-- 3D场景中插入新的几何体 辅助三维坐标系AxisHelper -->
      <canvas ref="myCanvas"></canvas>
    </div>
</template>

<script lang="ts">
import { Vue, Options } from 'vue-property-decorator';
import * as Three from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
@Options({ components: {
} })
export default class ThreeJsPrc14 extends Vue {
  public rect!: DOMRect;
  public scene!:  Three.Scene ;
  public cube!: Three.BoxGeometry;
  public sphere!: Three.SphereGeometry;
  public cylinder!: Three.CylinderGeometry;
  public material!: Three.MeshLambertMaterial;
  public material1!: Three.MeshLambertMaterial;
  public material2!: Three.MeshLambertMaterial;
  public mesh!: Three.Mesh;
  public mesh1!: Three.Mesh;
  public mesh2!: Three.Mesh;
  public camera!: Three.PerspectiveCamera;
  public renderer!: Three.WebGLRenderer;
  public t0!: Date;
  public t1!: Date;
  public t!: number;
  public controls!: OrbitControls;
  public axisHelper!: THREE.AxesHelper;


  public draw() {
    this.t1 = new Date();
    this.t = this.t1.getTime() - this.t0.getTime();
    this.t0 = this.t1;
    this.renderer.render(this.scene, this.camera);
    this.mesh.rotateX(0.001 * this.t);
    this.mesh.rotateY(0.001 * this.t);
    this.mesh.rotateZ(0.001 * this.t);

    requestAnimationFrame(() => {
      this.draw();
    });
  }
  public mounted() {
    this.rect = (this.$el as HTMLElement).getBoundingClientRect();
    // 场景
    this.scene = new Three.Scene();
    // 立方体网格模型
    this.cube = new Three.BoxGeometry(50, 50, 50);
    this.material = new Three.MeshLambertMaterial({
      color: 0x00ff00,
    });
    this.mesh = new Three.Mesh(this.cube, this.material);
    this.scene.add(this.mesh);
    // 球体网格模型
    this.sphere = new Three.SphereGeometry(30, 40, 40);
    this.material1 = new Three.MeshLambertMaterial({
      color: 0xff00ff,
    });
    this.mesh1 = new Three.Mesh(this.sphere, this.material1);
    this.mesh1.translateY(120);
    this.scene.add(this.mesh1);
    // 圆柱网格模型
    this.cylinder = new Three.CylinderGeometry(20, 20, 50, 20);
    this.material2 = new Three.MeshLambertMaterial({
      color: 0xff00ff,
    });
    this.mesh2 = new Three.Mesh(this.cylinder, this.material2);
    this.mesh2.position.set(80, 0, 0);
    this.scene.add(this.mesh2);

    this.axisHelper = new Three.AxesHelper(2500);
    this.scene.add(this.axisHelper);

    const point = new Three.PointLight(0xffffff);
    point.position.set(200, 200, 300);
    this.scene.add(point);
    const ambient = new Three.AmbientLight(0x4444);
    this.scene.add(ambient);

    // 相机
    this.camera = new Three.PerspectiveCamera(70, this.rect.width / this.rect.height, 1, 10000);
    this.camera.position.set(200, 100, 200);
    this.camera.lookAt(this.scene.position);

    // 渲染器
    const myCanvas = this.$refs.myCanvas as HTMLCanvasElement;
    this.renderer = new Three.WebGLRenderer({ canvas: myCanvas });
    this.renderer.setSize(this.rect.width, this.rect.height);
    this.renderer.setClearColor(0xb9d3ff, 1);

    this.t0 = new Date();
    this.draw();
    this.controls = new OrbitControls(this.camera, myCanvas);
    // 如果threejs代码中通过requestAnimationFrame()实现渲染器渲染方法render()的周期性调用，
    // 当通过OrbitControls操作改变相机状态的时候，没必要在通过controls.addEventListener('change', render)
    // 监听鼠标事件调用渲染函数，因为requestAnimationFrame()就会不停的调用渲染函数。
    // this.controls.addEventListener('change', this.draw);
  }
}
</script>

<style lang="postcss" scoped>
.threeJsPrc14{
  touch-action: none;
  width: 100%;
  height: 100%;
  background: grey;
}
</style>
